const _toString = Object.prototype.toString;
export function isPlainObject(obj) {
  return _toString.call(obj) === "[object Object]";
}

export function noop() { }

const _hasOwnProperty = Object.prototype.hasOwnProperty;
export function hasOwn(obj, key) {
  return _hasOwnProperty.call(obj, key);
}

const hyphenateRe = /\B([A-Z])/g;
export function hyphenate(str) {
  return str.replace(hyphenateRe, "-$1").toLowerCase();
}

// 这是超简单版本的defineReactive
export function defineReactive(obj, key, val, customSetter) {
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      return value;
    },
    set(newVal) {
      if (process.env.NODE_ENV !== 'production' && customSetter) {
        customSetter()
      }
      val = newVal;
    }
  })
}

const sharedPropertyDefinition = {
  enumerable: true,
  configurable: true,
  set: noop,
  get: noop,
}

export function proxy(target, sourceKey, key) {
  sharedPropertyDefinition.get = function () {
    return target[sourceKey][key];
  }
  sharedPropertyDefinition.set = function (value) {
    target[sourceKey][key] = value;
  }
  Object.defineProperty(target, key, sharedPropertyDefinition);
}

export function getTypeIndex(type, expectedTypes) {
  if (!Array.isArray(expectedTypes)) {
    return isSameType(expectedTypes, type) ? 0 : -1;
  }
  for (let i = 0, len = expectedTypes.length; i < len; i++) {
    if (isSameType(expectedTypes[i], type)) {
      return i
    }
  }
  return -1
}

function isSameType(a, b) {
  return getType(a) === getType(b);
}

const functionTypeCheckRE = /^\s*function (\w+)/;
function getType(fn) {
  const match = fn && fn.toString().match(functionTypeCheckRE);
  return match ? match[1] : "";
}

export function isObject(obj) {
  return typeof obj === 'object';
}